package demo1;

/**
 * 实例内部类
 * 1.如何获取实例内部类的对象?
 * 2.在实例内部类中,是否可以被定义静态的成员变量?
 *      public static int data6 = 6;
 * 3.当内部类数据成员和外部类数据成员是同名的时候？
 */

/*
1.获取实例内部类的对象的时候,依赖于外部类的对象;
要获得实例内部类对象,一定要先有外部类对象.
2.必须设置为public static final int data6 = 6;因为static成员不依赖于类的本身,所以最新啊执行的;
而实例内部类确实依赖于外部类的对象,之所以定义final类型,因为final修饰的是常量
类加载的时候,不会加载普通成员,内部类中又存在static,而static是在类加载的时候而创建的
3.那么我们用this和外部类类名.this来访问；实例内部类中包含了外部类的this；就近访问原则
 */
class OutClass1{
    public int data1 = 1;
    public int data2 = 2;
    public static int data3 = 3;

    class InnerClass{
        public int data1 = 11111;
        public int data4 = 4;
        private int data5 = 5;
        /*public static int data6 = 6;*/
        public static final int data6 = 6;
        public void test(){
            System.out.println(data1);//我们本意访问的是外部类,但是打印的是内部类的
            System.out.println(this.data1);//我们加上了this引用,这个时候表明这个data1是哪一类中的
            //所以我们如何访问外部类的data1呢？
            System.out.println(OutClass1.this.data1);//这个时候我们就要用外部类的this
            System.out.println(data5);
            System.out.println("内部类的test方法");
        }
    }

    public void test(){
        System.out.println("外部类的test方法");
        //访问内部类成员：
        /*System.out.println(data4);//这就报错了*/
        InnerClass innerClass = new InnerClass();
        System.out.println(innerClass.data4);
    }
}
public class Test2 {
    public static void main(String[] args) {

        OutClass1 outClass1 = new OutClass1();//外部类可以正常进行实例化
        System.out.println(outClass1.data1);

        System.out.println("================");
        //InnerClass innerClass = new InnerClass();
        //内部类不能上述般进行实例化

        //因为我们要使用外部类进行调用内部类（引用内部类）
        OutClass1.InnerClass innerClass = outClass1.new InnerClass();//我们用对象名去调用内部类名
        innerClass.test();

        //上述这种写法是把outClass的对象名给其去调用
        //我们也可以直接把对象引用:
        OutClass1.InnerClass innerClass2 = new OutClass1().new InnerClass();
        innerClass2.test();

        //内部类只能在外部类中的作用域内进行正常的实例化
    }
}
//缺点：我们每次使用实例内部类，都要先实例化外部类

/*
【注意事项】
        1. 外部类中的任何成员都可以在实例内部类方法中直接访问
        2. 实例内部类所处的位置与外部类成员位置相同，因此也受public、private，default访问限定符的约束
        3. 在实例内部类方法中访问同名的成员时，优先访问自己的，如果要访问外部类同名的成员，必须：外部类名
        称.this.同名成员 来访问
        4. 实例内部类对象必须在先有外部类对象前提下才能创建
        5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
        6. 外部类中，不能直接访问实例内部类中的成员，如果要访问必须先要创建内部类的对象。
*/

